#include "stdio.h"
#include "cim144.h"
//#include "encoding.h"
#include "util.h"

#define I1 576

uint8_t img [I1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int main(void){
    //int8_t zeros[576]={0};  
    uint64_t push_rs2 , save_rs2,mvm_rs2,mvm_rs1 ,config;
    //ROCC_push( (int64_t)zeros,576);
    int8_t fc1_out[96] = {0};
    int8_t fc2_out[16]  = {0};
    size_t cycles;
    cycles = -read_csr(cycle);
    //**************1.show img ******************
    // printf("\n**********show img*******************\n");
    // for(int i=0;i<484;i++){
    //     if(img[i]){
    //         printf("%c%c",'1',' ');
    //     }else{
    //         printf("%c%c",'-',' ');
    //     }
    //     if((i+1)%22==0){
    //         printf("\n");
    //     }
    // }

    //**************2.first layer input config******************
    push_rs2 = 0  << 11   | 576;  //reg: row start, num
    save_rs2 = 0  << 11   | (92+4) ;  //reg: col start, num
    mvm_rs2=   0  << 11   | 0;      //mvm: row_start, col_start
    mvm_rs1 = 484 << 16   | 92;     //mvm: row_num,   col_num
    config = 0<< 23 | 1 << 16 | 1<<8 | 0;
    ROCC_config(config);
    ROCC_push((int64_t)img ,push_rs2);
    ROCC_mvm(mvm_rs1,mvm_rs2);
    ROCC_save((int64_t)fc1_out,save_rs2);

    cycles += read_csr(cycle);
    printf("cycles: %d \n",cycles);
    cycles = -read_csr(cycle);

    //*********************3.relu**********************************
    for(int i=0;i < 92;i++){
        // printf("%4d ",fc1_out[i]);
        // if((i+1)%10==0){
        //     printf("\n");
        // }
        if(fc1_out[i]<0) {
            fc1_out[i]=0;
        }
    }
    // printf("\n");
    // for(int i=0;i < 92;i++){
    //     printf("%4d ",fc1_out[i]);
    //     if((i+1)%11==0){
    //         printf("\n");
    //     }
    // }

    // printf("\nfirst layer finish\n");

    cycles += read_csr(cycle);
    printf("cycles: %d \n",cycles);
    cycles = -read_csr(cycle);

    //**************4.second layer input config******************
    push_rs2 = 0   <<11  | 96;   //reg: row start, num
    save_rs2 = 96  <<11  | (10+6);   //reg: col start, num
    mvm_rs2  = 0   <<11  | 96;   //mvm: row_start, col_start
    mvm_rs1  = (92)<<16  | 10;   //mvm: row_num,   col_num
    config = 0<<23  |64<<16 | 4<< 8|0;
    ROCC_config(config);
    ROCC_push((int64_t)fc1_out ,push_rs2);
    ROCC_mvm(mvm_rs1,mvm_rs2);
    ROCC_save((int64_t)fc2_out ,save_rs2);
    cycles += read_csr(cycle);
    printf("cycles: %d \n",cycles);
    cycles = -read_csr(cycle);

    //**************5.print result******************
    int max = -65536;
    int num = 0;
    for(int i= 0;i< 10 ;i++){
	if(fc2_out[i]>max){
		max = fc2_out[i];
		num = i;
	}
        printf("%d ",fc2_out[i]);
    }

    printf("\npredict num %d\n",num);

    printf("\nsecond layer finish\n");


    return 0;    
}
